Handle updates to version requirements in lockfiles
authorAlex Crichton <alex@alexcrichton.com>
Thu, 27 Nov 2014 23:49:16 +0000 (15:49 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Thu, 27 Nov 2014 23:52:32 +0000 (15:52 -0800)
This is the same as the fix for #951 (fixed by #965). The relevant code was
erroneously looking at the source id when it should instead look at the entire
package id (name/version/source).

src/cargo/core/registry.rs
tests/test_cargo_registry.rs

index ed00428630e8315432a8775fd666138191e4b1ad..5ab42b30f381071600cb6525f522b4242231144b 100644 (file)
@@ -234,9 +234,10 @@ impl<'a> PackageRegistry<'a> {
                 //    sure to lock to precisely the given package id.
                 //
                 // 2. We have a lock entry for this dependency, but it's from a
-                //    different source than what's listed. In this case we must
-                //    discard the locked version because the listed source must
-                //    have changed.
+                //    different source than what's listed, or the version
+                //    requirement has changed. In this case we must discard the
+                //    locked version because the dependency needs to be
+                //    re-resolved.
                 //
                 // 3. We don't have a lock entry for this dependency, in which
                 //    case it was likely an optional dependency which wasn't
@@ -244,7 +245,7 @@ impl<'a> PackageRegistry<'a> {
                 Some(&(_, ref deps)) => {
                     match deps.iter().find(|d| d.get_name() == dep.get_name()) {
                         Some(lock) => {
-                            if lock.get_source_id() == dep.get_source_id() {
+                            if dep.matches_id(lock) {
                                 dep.lock_to(lock)
                             } else {
                                 dep
index 366453c7ac4059155a8f34d74d811a4c0329e101..8bb32cbc2249642b0587b57a71f61f23bd0c10be 100644 (file)
@@ -499,3 +499,62 @@ test!(bad_license_file {
                        .with_stderr("\
 the license file `foo` does not exist"));
 })
+
+test!(updating_a_dep {
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [project]
+            name = "foo"
+            version = "0.0.1"
+            authors = []
+
+            [dependencies.a]
+            path = "a"
+        "#)
+        .file("src/main.rs", "fn main() {}")
+        .file("a/Cargo.toml", r#"
+            [project]
+            name = "a"
+            version = "0.0.1"
+            authors = []
+
+            [dependencies]
+            bar = "*"
+        "#)
+        .file("a/src/lib.rs", "");
+    p.build();
+
+    r::mock_pkg("bar", "0.0.1", &[]);
+
+    assert_that(p.process(cargo_dir().join("cargo")).arg("build"),
+                execs().with_status(0).with_stdout(format!("\
+{updating} registry `[..]`
+{downloading} bar v0.0.1 (registry file://[..])
+{compiling} bar v0.0.1 (registry file://[..])
+{compiling} a v0.0.1 ({dir})
+{compiling} foo v0.0.1 ({dir})
+", updating = UPDATING, downloading = DOWNLOADING, compiling = COMPILING,
+   dir = p.url()).as_slice()));
+
+    File::create(&p.root().join("a/Cargo.toml")).write_str(r#"
+        [project]
+        name = "a"
+        version = "0.0.1"
+        authors = []
+
+        [dependencies]
+        bar = "0.1.0"
+    "#).unwrap();
+    r::mock_pkg("bar", "0.1.0", &[]);
+
+    println!("second");
+    assert_that(p.process(cargo_dir().join("cargo")).arg("build"),
+                execs().with_status(0).with_stdout(format!("\
+{updating} registry `[..]`
+{downloading} bar v0.1.0 (registry file://[..])
+{compiling} bar v0.1.0 (registry file://[..])
+{compiling} a v0.0.1 ({dir})
+{compiling} foo v0.0.1 ({dir})
+", updating = UPDATING, downloading = DOWNLOADING, compiling = COMPILING,
+   dir = p.url()).as_slice()));
+})